package com.yserp.project.erp.bill.payment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yserp.common.exception.BusinessException;
import com.yserp.common.utils.StringUtils;
import com.yserp.common.utils.bean.BeanUtils;
import com.yserp.common.utils.mybatis.MybatisPlusUtil;
import com.yserp.common.utils.text.Convert;
import com.yserp.project.erp.bill.payment.domain.Payment;
import com.yserp.project.erp.bill.payment.domain.PaymentDto;
import com.yserp.project.erp.bill.payment.domain.PaymentItem;
import com.yserp.project.erp.bill.payment.domain.PaymentVo;
import com.yserp.project.erp.bill.payment.mapper.PaymentMapper;
import com.yserp.project.erp.bill.payment.service.IPaymentItemService;
import com.yserp.project.erp.bill.payment.service.IPaymentService;
import com.yserp.project.erp.common.enums.CheckStatusEnums;
import com.yserp.project.erp.common.enums.OrderEnums;
import com.yserp.project.erp.common.enums.PayStatusEnums;
import com.yserp.project.erp.common.util.DateSearchUtils;
import com.yserp.project.erp.order.purchorder.domain.PurchOrder;
import com.yserp.project.erp.order.purchorder.service.IPurchOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 商品入库单主Service业务层处理
 *
 * @author yserp
 * @date 2022-08-08
 */
@Service
public class PaymentServiceImpl extends ServiceImpl<PaymentMapper, Payment> implements IPaymentService {
    @Resource
    private PaymentMapper paymentMapper;
    @Autowired
    private IPaymentItemService paymentItemService;
    @Autowired
    private IPurchOrderService purchOrderService;


    /**
     * 查询详情
     *
     * @param id 订单主键
     * @return 订单
     */
    @Override
    public PaymentVo selectPaymentById(Long id){
        return PaymentVo.builder().payment(paymentMapper.selectById(id))
                .items(paymentItemService.selectPaymentItemListByMainId(id))
                .build();
    }

    /**
     * 查询付款单列表
     *
     * @param payment
     * @return
     */
    @Override
    public List<Payment> selectPaymentList(Payment payment) {
        QueryWrapper<Payment> queryWrapper = new QueryWrapper<>();
        MybatisPlusUtil.notNullField(payment, queryWrapper);
        //对时间区间的处理
        DateSearchUtils.queryDateRange(payment,queryWrapper);
        return paymentMapper.selectList(queryWrapper);
    }

    /**
     * 新增
     *
     * @param paymentDto
     * @return 结果
     */
    @Override
    @Transactional
    public int insertPayment(PaymentDto paymentDto) {
        List<PaymentItem> items = paymentDto.getItems();
        if (CollectionUtils.isEmpty(items)) {
            throw new BusinessException("子表不能为空");
        }
        //验证单号是否存在
        String orderNo = paymentDto.getOrderCode();
        if(StringUtils.isBlank(orderNo)){
            throw new BusinessException("单号不存在");
        }
        Integer count = paymentMapper.selectCount(new QueryWrapper<Payment>().eq("order_code", orderNo));
        if(count>0){
            throw new BusinessException("单号已存在，请重新下单");
        }else{
            OrderEnums.putCacheOrderNo(orderNo);
        }
        //插入主表
        Payment payment = new Payment();
        BeanUtils.copyBeanProp(payment, paymentDto);
        int i = paymentMapper.insert(payment);
        //批量插入子表
        items.stream().forEach(item -> item.setMainId(payment.getId()));
        paymentItemService.saveBatch(items);
        return i;
    }

    /**
     * 修改
     *
     * @param paymentDto
     * @return 结果
     */
    @Override
    @Transactional
    public int updatePayment(PaymentDto paymentDto) {
        List<PaymentItem> items = paymentDto.getItems();
        if (CollectionUtils.isEmpty(items)) {
            throw new BusinessException("子表不能为空");
        }
        //修改主表(运用了乐观锁)
        Payment payment = paymentMapper.selectById(paymentDto.getId());
        BeanUtils.copyBeanProp(payment, paymentDto);
        int i = paymentMapper.updateById(payment);
        //子表
        Long mainId = payment.getId();
        //获取子表
        List<PaymentItem> paymentItems = paymentItemService.selectPaymentItemListByMainId(mainId);
        if (!CollectionUtils.isEmpty(paymentItems)) {
            List<Long> oldIds = paymentItems.stream().map(PaymentItem::getId).collect(Collectors.toList());
            List<Long> newIds = items.stream().map(PaymentItem::getId).collect(Collectors.toList());
            oldIds.removeAll(newIds);
            if (!CollectionUtils.isEmpty(oldIds)) {
                paymentItemService.removeByIds(oldIds);
            }
        }
        for (PaymentItem item : items) {
            item.setMainId(mainId);
            paymentItemService.saveOrUpdate(item);
        }
        return i;
    }

    /**
     * 批量删除商品入库单主
     *
     * @param ids 需要删除的商品入库单主主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deletePaymentByIds(String ids) {
        int result = 0;
        Long[] mainIds = Convert.toLongArray(ids);
        for (Long id : mainIds) {
            result = this.deletePaymentById(id);
            if (result <= 0) {
                break;
            }
        }
        return result;
    }

    @Override
    @Transactional
    public int auditPaymentByIds(String ids) {
        Payment payment = null;
        Long[] mainIds = Convert.toLongArray(ids);
        for (Long id : mainIds) {
            payment = paymentMapper.selectById(id);
            //如果已审核，无须再次审核
            if(CheckStatusEnums.OK_CHECK.getCode().equals(payment.getOrderStatus())){
                continue;
            }
            //1.更新状态
            payment.setOrderStatus(CheckStatusEnums.OK_CHECK.getCode());
            paymentMapper.updateById(payment);
            //2.同步采购单数据
            List<PaymentItem> items = paymentItemService.selectPaymentItemListByMainId(id);
            for (PaymentItem item : items) {
                PurchOrder purchOrder = purchOrderService.getById(item.getPurchId());
                //付款状态
                BigDecimal payAmount = item.getPayAmount();
                BigDecimal noPayAmount = item.getNoPayAmount();
                if (noPayAmount.compareTo(payAmount)==0) {
                    purchOrder.setPayStatus(PayStatusEnums.OK_PAYMENT.getCode());
                }else{
                    purchOrder.setPayStatus(PayStatusEnums.PART_PAYMENT.getCode());
                }
                //付款金额
                BigDecimal payAmounts = purchOrder.getPayAmounts();
                payAmounts = payAmounts.add(payAmount);
                purchOrder.setPayAmounts(payAmounts);
                purchOrderService.updateById(purchOrder);
            }
        }
        return 1;
    }

    /**
     * 主子表同时删除
     *
     * @param id
     * @return
     */
    private int deletePaymentById(Long id) {

        int result = 0;
        //更新主表
        int i = paymentMapper.deleteById(id);
        //查询子表信息
        List<PaymentItem> items = paymentItemService.selectPaymentItemListByMainId(id);
        if (!CollectionUtils.isEmpty(items)) {
            List<Long> itemIds = items.stream().map(PaymentItem::getId).collect(Collectors.toList());
            boolean b = paymentItemService.removeByIds(itemIds);
            if (i > 0 && b) {
                result = 1;
            }
        }
        return result;
    }

}
